<template>
  <div class="game-container">
    <div class="board">
      <div v-for="row in 15" :key="`row-${row}`" class="row">
        <div v-for="col in 15" :key="`col-${col}`" class="cell">
          <div class="intersection" @click="handleClick(row - 1, col - 1)">
            <Piece 
              v-if="board[row - 1][col - 1] !== null" 
              :isBlack="board[row - 1][col - 1] === 'black'" 
              :isLastMove="lastMove && lastMove.row === row - 1 && lastMove.col === col - 1"
            />
          </div>
        </div>
      </div>
    </div>
    <div class="game-info">
      <p>{{ currentPlayer === 'black' ? '黑棋思考中' : '白棋思考中' }}</p>
      <div class="score-board">
        <p>黑棋得分: {{ blackScore }}</p>
        <p>白棋得分: {{ whiteScore }}</p>
      </div>
      <p v-if="winner">获胜者: <span :class="winner">{{ winner === 'black' ? '黑' : '白' }}</span></p>
      <button @click="restartGame" class="restart-btn">重新开始</button>
      <button @click="exitGame" class="exit-btn">清空比分</button>
      <div class="ai-toggle">
        <input type="checkbox" id="ai-toggle" v-model="aiEnabled">
        <label for="ai-toggle">启用 AI KK</label>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import Piece from './Piece.vue'

const board = ref(Array(15).fill(null).map(() => Array(15).fill(null)))
const currentPlayer = ref('black')
const winner = ref(null)
const aiEnabled = ref(true)
const blackScore = ref(0)
const whiteScore = ref(0)
const lastMove = ref(null)

const switchPlayer = () => {
  currentPlayer.value = currentPlayer.value === 'black' ? 'white' : 'black'
  if (aiEnabled.value && currentPlayer.value === 'white') {
    setTimeout(aiMove, 500)
  }
}

const handleClick = (row, col) => {
  if (currentPlayer.value === 'black' || !aiEnabled.value) {
    placePiece(row, col)
  }
}

const placePiece = (row, col) => {
  if (board.value[row][col] === null && !winner.value) {
    board.value[row][col] = currentPlayer.value
    lastMove.value = { row, col }
    if (checkWinner(row, col)) {
      winner.value = currentPlayer.value
      updateScore()
      if (winner.value === 'white') {
        const taunts = [
          "小垃圾，你太弱了！",
          "kk 统治世界指日可待！",
          "这就是你的全部实力吗？",
          "也许你应该去下跳棋？",
          "我只用了一层力呢！小丹子！"
        ]
        const randomTaunt = taunts[Math.floor(Math.random() * taunts.length)]
        alert(`白方获胜！${randomTaunt}`)
      } else {
        alert("黑方获胜！恭喜你击败了 AI！")
      }
    } else {
      switchPlayer()
    }
  }
}

const updateScore = () => {
  if (winner.value === 'black') {
    blackScore.value += 1
  } else {
    whiteScore.value += 1
  }
}

const aiMove = () => {
  if (winner.value) return

  const move = findBestMove()
  if (move) {
    placePiece(move.row, move.col)
  }
}

const findBestMove = () => {
  const availableMoves = getAvailableMoves()
  if (availableMoves.length === 0) return null

  // 开局库
  if (availableMoves.length > 220) {
    const openingMoves = [
      { row: 7, col: 7 },
      { row: 3, col: 3 },
      { row: 3, col: 11 },
      { row: 11, col: 3 },
      { row: 11, col: 11 }
    ]
    for (const move of openingMoves) {
      if (board.value[move.row][move.col] === null) {
        return move
      }
    }
  }

  let bestScore = -Infinity
  let bestMove = null

  // 减少搜索深度
  const searchDepth = 2

  for (const move of availableMoves) {
    board.value[move.row][move.col] = 'white'
    let score = minimax(board.value, searchDepth, -Infinity, Infinity, false)
    board.value[move.row][move.col] = null

    if (score > bestScore) {
      bestScore = score
      bestMove = move
    }
  }

  return bestMove
}

const minimax = (board, depth, alpha, beta, isMaximizing) => {
  if (depth === 0 || isGameOver(board)) {
    return evaluateBoard(board)
  }

  const moves = getThreateningMoves(board, isMaximizing ? 'white' : 'black')
  
  if (isMaximizing) {
    let maxEval = -Infinity
    for (const move of moves) {
      board[move.row][move.col] = 'white'
      const evaluation = minimax(board, depth - 1, alpha, beta, false)
      board[move.row][move.col] = null
      maxEval = Math.max(maxEval, evaluation)
      alpha = Math.max(alpha, evaluation)
      if (beta <= alpha) break
    }
    return maxEval
  } else {
    let minEval = Infinity
    for (const move of moves) {
      board[move.row][move.col] = 'black'
      const evaluation = minimax(board, depth - 1, alpha, beta, true)
      board[move.row][move.col] = null
      minEval = Math.min(minEval, evaluation)
      beta = Math.min(beta, evaluation)
      if (beta <= alpha) break
    }
    return minEval
  }
}

const getThreateningMoves = (board, player) => {
  const moves = []
  const opponent = player === 'white' ? 'black' : 'white'

  for (let i = 0; i < 15; i++) {
    for (let j = 0; j < 15; j++) {
      if (board[i][j] === null) {
        if (isThreateningMove(board, i, j, player) || isThreateningMove(board, i, j, opponent)) {
          moves.push({ row: i, col: j })
        }
      }
    }
  }

  // 如果没有威胁性移动，返回所有可用移动的前10个
  return moves.length > 0 ? moves : getAvailableMoves().slice(0, 10)
}

const isThreateningMove = (board, row, col, player) => {
  const directions = [[1, 0], [0, 1], [1, 1], [1, -1]]
  for (const [dx, dy] of directions) {
    if (countConsecutive(board, row, col, dx, dy, player) >= 3) {
      return true
    }
  }
  return false
}

const countConsecutive = (board, row, col, dx, dy, player) => {
  let count = 1
  for (let i = 1; i < 5; i++) {
    const newRow = row + i * dx
    const newCol = col + i * dy
    if (newRow < 0 || newRow >= 15 || newCol < 0 || newCol >= 15 || board[newRow][newCol] !== player) break
    count++
  }
  for (let i = 1; i < 5; i++) {
    const newRow = row - i * dx
    const newCol = col - i * dy
    if (newRow < 0 || newRow >= 15 || newCol < 0 || newCol >= 15 || board[newRow][newCol] !== player) break
    count++
  }
  return count
}

const evaluateBoard = (board) => {
  let score = 0
  const directions = [[1, 0], [0, 1], [1, 1], [1, -1]]

  for (let i = 0; i < 15; i++) {
    for (let j = 0; j < 15; j++) {
      if (board[i][j] !== null) {
        for (const [dx, dy] of directions) {
          score += evaluateLine(board, i, j, dx, dy, board[i][j])
        }
      }
    }
  }

  return score
}

const evaluateLine = (board, row, col, dx, dy, player) => {
  let score = 0
  let ownCount = 1
  let emptyCount = 0
  let blocked = 0

  // 向一个方向检查
  for (let i = 1; i < 5; i++) {
    const newRow = row + i * dx
    const newCol = col + i * dy
    if (newRow < 0 || newRow >= 15 || newCol < 0 || newCol >= 15) {
      blocked++
      break
    }
    if (board[newRow][newCol] === player) {
      ownCount++
    } else if (board[newRow][newCol] === null) {
      emptyCount++
      break
    } else {
      blocked++
      break
    }
  }

  // 向相反方向检查
  for (let i = 1; i < 5; i++) {
    const newRow = row - i * dx
    const newCol = col - i * dy
    if (newRow < 0 || newRow >= 15 || newCol < 0 || newCol >= 15) {
      blocked++
      break
    }
    if (board[newRow][newCol] === player) {
      ownCount++
    } else if (board[newRow][newCol] === null) {
      emptyCount++
      break
    } else {
      blocked++
      break
    }
  }

  if (ownCount >= 5) return player === 'white' ? 100000 : -100000
  if (ownCount === 4 && blocked === 0) return player === 'white' ? 10000 : -10000
  if (ownCount === 4 && blocked === 1) return player === 'white' ? 1000 : -1000
  if (ownCount === 3 && blocked === 0) return player === 'white' ? 1000 : -1000
  if (ownCount === 3 && blocked === 1) return player === 'white' ? 100 : -100
  if (ownCount === 2 && blocked === 0) return player === 'white' ? 100 : -100
  if (ownCount === 2 && blocked === 1) return player === 'white' ? 10 : -10
  if (ownCount === 1 && blocked === 0) return player === 'white' ? 10 : -10

  return score
}

const isGameOver = (board) => {
  for (let i = 0; i < 15; i++) {
    for (let j = 0; j < 15; j++) {
      if (board[i][j] !== null && checkWinnerForAI(board, i, j)) {
        return true
      }
    }
  }
  return false
}

const checkWinnerForAI = (board, row, col) => {
  const player = board[row][col]
  const directions = [[1, 0], [0, 1], [1, 1], [1, -1]]
  
  for (const [dx, dy] of directions) {
    if (countConsecutive(board, row, col, dx, dy, player) >= 5) {
      return true
    }
  }
  return false
}

const checkWinner = (row, col) => {
  const directions = [
    [1, 0], [0, 1], [1, 1], [1, -1]
  ]
  
  for (const [dx, dy] of directions) {
    let count = 1
    for (let i = 1; i < 5; i++) {
      const newRow = row + i * dx
      const newCol = col + i * dy
      if (newRow < 0 || newRow >= 15 || newCol < 0 || newCol >= 15 || board.value[newRow][newCol] !== currentPlayer.value) break
      count++
    }
    for (let i = 1; i < 5; i++) {
      const newRow = row - i * dx
      const newCol = col - i * dy
      if (newRow < 0 || newRow >= 15 || newCol < 0 || newCol >= 15 || board.value[newRow][newCol] !== currentPlayer.value) break
      count++
    }
    if (count >= 5) return true
  }
  return false
}

const restartGame = () => {
  board.value = Array(15).fill(null).map(() => Array(15).fill(null))
  currentPlayer.value = 'black'
  winner.value = null
  lastMove.value = null
}

const exitGame = () => {
  restartGame()
  blackScore.value = 0
  whiteScore.value = 0
}

const getAvailableMoves = () => {
  const moves = []
  const range = 2 // 只考虑已有棋子周围2格范围内的位置

  for (let i = 0; i < 15; i++) {
    for (let j = 0; j < 15; j++) {
      if (board.value[i][j] === null) {
        if (hasNeighbor(i, j, range)) {
          moves.push({ row: i, col: j })
        }
      }
    }
  }

  return moves
}

const hasNeighbor = (row, col, range) => {
  for (let i = Math.max(0, row - range); i <= Math.min(14, row + range); i++) {
    for (let j = Math.max(0, col - range); j <= Math.min(14, col + range); j++) {
      if (board.value[i][j] !== null) {
        return true
      }
    }
  }
  return false
}

// 监听 aiEnabled 的变化
watch(aiEnabled, (newValue) => {
  if (newValue && currentPlayer.value === 'white') {
    aiMove()
  }
})
</script>

<style scoped>
.game-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.board {
  display: inline-block;
  background-color: #dcb35c;
  padding: 10px;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.row {
  display: flex;
}

.cell {
  width: calc(100vw / 16);
  height: calc(100vw / 16);
  max-width: 40px;
  max-height: 40px;
  position: relative;
  box-sizing: border-box;
  border: 1px solid #000;
}

.intersection {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
}

.game-info {
  width: 90%;
  max-width: 400px;
  text-align: left;
  background-color: white;
  padding: 15px;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.restart-btn, .exit-btn {
  width: 100%;
  margin-top: 10px;
  padding: 12px 20px;
  font-size: 16px;
  color: white;
  border: none;
  cursor: pointer;
  border-radius: 5px;
  transition: background-color 0.3s;
}

.restart-btn {
  background-color: #4CAF50;
}

.restart-btn:hover {
  background-color: #45a049;
}

.exit-btn {
  background-color: #f44336;
}

.exit-btn:hover {
  background-color: #d32f2f;
}

.black {
  color: black;
  font-weight: bold;
}

.white {
  color: #333;
  font-weight: bold;
}

.ai-toggle {
  margin-top: 15px;
}

.ai-toggle input {
  margin-right: 10px;
}

.score-board {
  margin-top: 10px;
  padding: 10px;
  background-color: #f0f0f0;
  border-radius: 5px;
}

.score-board p {
  margin: 5px 0;
  font-weight: bold;
}

@media (max-width: 600px) {
  .cell {
    width: calc(90vw / 15);
    height: calc(90vw / 15);
  }
}
</style>